#define __USE_MINGW_ANSI_STDIO 1

#include <math.h>
#include <stdio.h>

#define MAXN 19

char *bunits[] = {"", "万", "亿", "万亿", "亿亿"};
char *sunits[] = {"", "拾", "佰", "仟"};
char *captb[] = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};

void capRMB(long long m) {
    if (!m) {
        puts("零元整");
        return;
    }
    // digits: 数字位数
    // iszero: 前面数码为零标记
    // mtb:    数字归组
    int digits    = log10(m) + 1;
    int iszero    = 0;
    int mtb[MAXN] = {0};
    for (int i = digits - 1; m; i--, m /= 10)
        mtb[i] = m % 10;
    for (int i = 0; i < digits; i++) {
        // curdig: 将当前循环标号 i 映射到实际情况
        //         比如 1,0342,0221. 当 i = 1 时 curdig = 7
        //         表示当前的数在千万位上, curig = 0 表示个位
        int curdig = digits - 1 - i;
        // 遇非零数字则判断前面是否有零, 如有则打印零
        // 如遇零则仅设立零标记, 为后来遇到的非零数字作准备
        // 打印数字以及千百十位
        if (mtb[i]) {
            if (iszero)
                printf("零"), iszero = 0;
            printf("%s", captb[mtb[i]]);
            printf("%s", sunits[curdig % 4]);
        } else {
            iszero = 1;
        }
        // 打印大数位, 如万、亿
        // 万、亿整数倍的时候需要额外判断
        if (curdig % 4 == 0) {
            int checkzerosum = 0;
            for (int j = i; j >= 0 && j >= i - 3; j--)
                checkzerosum += mtb[j];
            if (checkzerosum)
                printf("%s", bunits[curdig / 4]);
        }
    }
    puts("元整");
}

int main() {
    long long money;
    while (scanf("%lld", &money) == 1)
        printf("%20lld: ", money), capRMB(money);

    return 0;
}
